package com.tom.architect02.ui30.day21;

import android.content.Context;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;

import androidx.annotation.Nullable;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
import com.tom.architect02.R;
import android.animation.ObjectAnimator;
import android.util.Log;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;

/**
 * Added by Tom on 2024/06/20.
 * 58同城，加载动画效果。
 */
public class LoadingView extends LinearLayout {
    private ShapeView mShapeView;// 上面的形状
    private View mShadowView;// 中间的阴影
    private int mTranslationDistance = 0; // 垂直移动的距离
    private final long ANIMATOR_DURATION = 350; // 动画执行的时间
    private boolean mIsStopAnimator = false; // 是否停止动画

    public LoadingView(Context context) {
        this(context, null);
    }

    public LoadingView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public LoadingView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mTranslationDistance = dip2px(80);
        initLayout();

        initDownAnimator();
        initUpAnimator();
    }

    private AnimatorSet mFallAnimatorSet, mUpAnimatorSet;
    private void initDownAnimator() {
        // 动画作用在谁的身上
        // 下落位移动画
        ObjectAnimator translationAnimator = ObjectAnimator.ofFloat(mShapeView,"translationY",0,mTranslationDistance);
        //translationAnimator.setDuration(ANIMATOR_DURATION);
        // 配合中间阴影缩小
        ObjectAnimator scaleAnimator = ObjectAnimator.ofFloat(mShadowView,"scaleX",1f,0.3f);
        //scaleAnimator.setDuration(ANIMATOR_DURATION);

        mFallAnimatorSet = new AnimatorSet();
        mFallAnimatorSet.setDuration(ANIMATOR_DURATION);
        // 下落的速度应该是越来越快，插值器
        mFallAnimatorSet.setInterpolator(new AccelerateInterpolator());
        mFallAnimatorSet.playTogether(translationAnimator,scaleAnimator);
        // 先执行 translationAnimator, 接着执行 scaleAnimator
        // animatorSet.playSequentially(translationAnimator,scaleAnimator);
        // 下落完之后就上抛了，监听动画执行完毕
        // 是一种思想，在 Adapter 中的 BannerView 写过
        mFallAnimatorSet.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                // 改变形状
                mShapeView.exchange();
                // 下落完之后就上抛了
                startUpAnimator();
            }
        });
    }

    private void initUpAnimator() {
        // 动画作用在谁的身上
        // 下落位移动画
        ObjectAnimator translationAnimator = ObjectAnimator.ofFloat(mShapeView,"translationY",mTranslationDistance,0);
        //translationAnimator.setDuration(ANIMATOR_DURATION);
        // 配合中间阴影缩小
        ObjectAnimator scaleAnimator = ObjectAnimator.ofFloat(mShadowView,"scaleX",0.3f,1f);
        //scaleAnimator.setDuration(ANIMATOR_DURATION);

        mUpAnimatorSet = new AnimatorSet();
        mUpAnimatorSet.setDuration(ANIMATOR_DURATION);
        mUpAnimatorSet.setInterpolator(new DecelerateInterpolator());
        mUpAnimatorSet.playTogether(translationAnimator, scaleAnimator);
        // 先执行 translationAnimator 接着执行 scaleAnimator
        // animatorSet.playSequentially(translationAnimator,scaleAnimator);
        // animatorSet.addListener(new Animator.AnimatorListener() {})
        // 上抛完之后就下落了，监听动画执行完毕
        // 是一种思想，在 Adapter中的 BannerView 万能轮播写过, AnimatorListenerAdapter不要复写所有的方法。
        mUpAnimatorSet.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                // 上抛完之后, 就下落了
                startFallAnimator();
            }
            @Override
            public void onAnimationStart(Animator animation) {
                // 开始旋转
                startRotationAnimator();
            }
        });
    }


    private int dip2px(int dip) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dip,getResources().getDisplayMetrics());
    }

    // 初始化加载布局，写好的ui_loading_view
    private void initLayout() {
        // 1.1 实例化View
//         View loadView = inflate(getContext(),R.layout.ui_loading_view,null);
        // 1.2 添加到该View
        // addView(loadView);
        // 找一下 插件式换肤资源加载的那一节的内容

        // this 代表把 ui_loading_view 加载到自定义的 LoadingView 中. this代表parent
        inflate(getContext(), R.layout.ui_loading_view,this);
        mShapeView = findViewById(R.id.shape_view);
        mShadowView = findViewById(R.id.shadow_view);
        post(new Runnable() {
            @Override
            public void run() {
                // onResume 之后的View绘制流程执行完毕之后（View的绘制流程源码分析那一章）
                startFallAnimator();
            }
        });
        //startFallAnimator(); //相当于onCreate() 方法中执行 ，布局文件解析后 反射创建实例
    }

    // 开始下落动画
    private void startFallAnimator() {
        if(mIsStopAnimator) return; // 已停止动画
        mFallAnimatorSet.start();
    }

    /**
     * 开始执行上抛动画
     */
    private void startUpAnimator() {
        if(mIsStopAnimator) return;
        Log.e("TAG","startUpAnimator"+this);
        // 执行 -> 监听的 onAnimationStart 方法
        mUpAnimatorSet.start();
    }

    /**
     * 上抛的时候需要旋转
     */
    private void startRotationAnimator() {
        ObjectAnimator rotationAnimator = null;
//        mShapeView.setRotation(); // rotation
        switch (mShapeView.getCurrentShape()){
            case Circle: // 圆形
            case Square:
                // 正方形：180°
                rotationAnimator = ObjectAnimator.ofFloat(mShapeView,"rotation",0,180);
                break;
            case Triangle:
                // 三角形：-120°
                rotationAnimator = ObjectAnimator.ofFloat(mShapeView,"rotation",0,-120);
                break;
        }
        rotationAnimator.setDuration(ANIMATOR_DURATION);
        rotationAnimator.setInterpolator(new DecelerateInterpolator());
        rotationAnimator.start();
    }

    // 数据已放回了，设置动画为不可见。
    @Override
    public void setVisibility(int visibility) {
        // INVISIBLE：不要再去摆放和计算，少走一些系统的源码（View的绘制流程）
        super.setVisibility(View.INVISIBLE);
        // 清理动画
        mShapeView.clearAnimation();
        mShadowView.clearAnimation();
        // 把LoadingView从父布局移除
        ViewGroup parent = (ViewGroup) getParent();
        if(parent != null){
            removeAllViews();// 移除自己所有的View
            parent.removeView(this);// 从父布局移除
        }
        mIsStopAnimator = true; // 停止动画
    }

}
